﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zen4SyncPOCO.POCO.MergeSync;
using System.Data.SqlServerCe;
using System.IO;

namespace Zen4SyncClient.ActivityExecutors
{
    /// <summary>
    /// Provides methods to execute activities of the "Merge Sync" type.
    /// </summary>
    internal static class MergeSync
    {
        internal static void ExecuteSyncSession(SyncSession activity, SyncSessionContext context)
        {
            SqlCeReplication sqlCeReplication = new SqlCeReplication();

            sqlCeReplication.CompressionLevel = activity.syncSession_compressionLevel;
            sqlCeReplication.ConnectionRetryTimeout = activity.syncSession_connectionRetryTimeout;
            sqlCeReplication.ConnectTimeout = activity.syncSession_connectTimeout;
            sqlCeReplication.ExchangeType = EnumConverter.ConvertExchangeType(activity.syncSession_exchangeTypeEnum);
            sqlCeReplication.HostName = activity.syncSession_hostName;
            sqlCeReplication.LoginTimeout = activity.syncSession_loginTimeout;
            sqlCeReplication.PostSyncCleanup = activity.syncSession_postSyncCleanup;
            sqlCeReplication.Publication = activity.syncSession_publication;
            sqlCeReplication.QueryTimeout = activity.syncSession_queryTimeout;
            sqlCeReplication.ReceiveTimeout = sqlCeReplication.ReceiveTimeout;
            sqlCeReplication.SendTimeout = sqlCeReplication.SendTimeout;
            sqlCeReplication.SnapshotTransferType = EnumConverter.ConvertSnapshotTransferType(activity.syncSession_snapshotTransferTypeEnum);

            // Publisher
            Publisher publisher = activity.syncSession_publisher;
            sqlCeReplication.Publisher = publisher.publisher_name;
            sqlCeReplication.PublisherAddress = publisher.publisher_address;
            sqlCeReplication.PublisherDatabase = publisher.publisher_database;
            if (!String.IsNullOrEmpty(publisher.publisher_login)) sqlCeReplication.PublisherLogin = publisher.publisher_login;
            if (!String.IsNullOrEmpty(publisher.publisher_password)) sqlCeReplication.PublisherPassword = publisher.publisher_password;
            sqlCeReplication.PublisherNetwork = EnumConverter.ConvertNetworkType(publisher.publisher_networkTypeEnum);
            sqlCeReplication.PublisherSecurityMode = EnumConverter.ConvertSecurityType(publisher.publisher_securityTypeEnum);

            // Distributor
            Distributor distributor = activity.syncSession_distributor;
            if (!String.IsNullOrEmpty(distributor.distributor_name)) sqlCeReplication.Distributor = distributor.distributor_name;
            if (!String.IsNullOrEmpty(distributor.distributor_address)) sqlCeReplication.DistributorAddress = distributor.distributor_address;
            if (!String.IsNullOrEmpty(distributor.distributor_login)) sqlCeReplication.DistributorLogin = distributor.distributor_login;
            if (!String.IsNullOrEmpty(distributor.distributor_password)) sqlCeReplication.DistributorPassword = distributor.distributor_password;
            sqlCeReplication.DistributorNetwork = EnumConverter.ConvertNetworkType(distributor.distributor_networkTypeEnum);
            sqlCeReplication.DistributorSecurityMode = EnumConverter.ConvertSecurityType(distributor.distributor_securityTypeEnum);
            if (!String.IsNullOrEmpty(distributor.distributor_profileName)) sqlCeReplication.ProfileName = distributor.distributor_profileName;

            // Internet
            Internet internet = activity.syncSession_internet;
            if (!String.IsNullOrEmpty(internet.internet_url))sqlCeReplication.InternetUrl = internet.internet_url;
            if (!String.IsNullOrEmpty(internet.internet_login))sqlCeReplication.InternetLogin = internet.internet_login;
            if (!String.IsNullOrEmpty(internet.internet_password))sqlCeReplication.InternetPassword = internet.internet_password;
            if (!String.IsNullOrEmpty(internet.internet_proxyServer))sqlCeReplication.InternetProxyServer = internet.internet_proxyServer;
            if (!String.IsNullOrEmpty(internet.internet_proxyLogin))sqlCeReplication.InternetProxyLogin = internet.internet_proxyLogin;
            if (!String.IsNullOrEmpty(internet.internet_proxyPassword))sqlCeReplication.InternetProxyPassword = internet.internet_proxyPassword;

            // Subscriber
            Subscriber subscriber = context.syncSessionContext_subscriber;
            sqlCeReplication.Subscriber = subscriber.subscriber_name;
            if (!String.IsNullOrEmpty(subscriber.subscriber_hostName)) sqlCeReplication.HostName = subscriber.subscriber_hostName;
            sqlCeReplication.Validate = EnumConverter.ConvertValidateType(subscriber.subscriber_validateTypeEnum);
            
            string sdfCompletePath = Path.Combine(subscriber.subscriber_sdfFileDirectory, subscriber.subscriber_sdfFileName);
            sqlCeReplication.SubscriberConnectionString = String.Format(subscriber.subscriber_connectionString, sdfCompletePath);

            if (subscriber.subscriber_deleteSdfIfItExists && File.Exists(sdfCompletePath))
            {
                File.Delete(sdfCompletePath);
            }

            if (!File.Exists(sdfCompletePath))
            {
                sqlCeReplication.AddSubscription(AddOption.CreateDatabase);
            }

            if (context.syncSessionContext_subscriber.subscriber_reinitializeSubscription)
            {
                sqlCeReplication.ReinitializeSubscription(context.syncSessionContext_subscriber.subscriber_uploadBeforeReinitialize);
            }

            if (Program.DebugLogEnabled) Program.Logger.LogMessage(String.Format("Starting synchronization with connection string : {0}", sqlCeReplication.SubscriberConnectionString));
            
            sqlCeReplication.Synchronize();

            if (Program.DebugLogEnabled) Program.Logger.LogMessage("Synchronization completed");
        }
    }
}
